第 9 章:Ansible 最佳實踐
官方建議的目錄結構
官方建議的目錄結構
production # inventory file for production.
staging # inventory file for staging.
group_vars/
group1 # here we assign variables to particular groups
group2
host_vars/
hostname1 # if systems need specific variables, put them here
hostname2
site.yml # master playbook
webservers.yml # playbook for webserver tier
dbservers.yml # playbook for dbserver tier
roles/
common/ # role name
tasks/ #
main.yml # main tasks file.
handlers/ #
main.yml # handlers file.
templates/ #
ntp.conf.j2 # templates end in .j2.
files/ #
bar.txt # files
foo.sh # script files
vars/ #
main.yml # variables with this role.
defaults/ #
main.yml # default variables.
meta/ #
main.yml # role dependencies
production,staging:藉由 inventory file 來切換環境webservers.yml:網頁伺服器一層的 playbook。dbservers.yml:資料庫伺服器一層的 playbook。django
django 專案目錄結構範例
django 專案目錄結構範例
README.md # 該專案的說明文件。
Vagrantfile
ansible.cfg # configure for ansible
files/
id_rsa_deploy # 用 Git 部署的 ssh key。
ssl_key/
...
group_vars/
all # 各環境共用的群組變數。
local # 本機開發的群組變數。
production # 正式環境的群組變數。
staging # 測試環境的群組變數。
production # 正式環境的 inventory file。
requirements.yml
restart_service.yml # 重開 API 服務的 playbook。
roles/
chusiang.switch-apt-mirror/
...
setup.yml # 主要 playbook。
staging # 測試環境的 inventory file。
tasks/
restart_api.yml # 重開 api 的 tasks。
setting_api.yml # 設定 api 的 tasks。
setting_nginx.yml # 設定 nginx 的 tasks。
setup.yml # 主要安裝流程的 tasks。
templates/
local_settings.py.j2
nginx.conf.j2 # nginx vhost.
nginx_ssl.conf # nginx vhost (ssl).
supervisor.conf.j2
tests/
Dockerfile # 用 Docker 跑測試。
update_config.yml
Vagrantfile:在本機主要使用 Vagrant 搭配group_vars/local進行開發。ansible.cfg:依各專案客製 Ansible 相關環境。files/:集中管理要使用 files module 複製到 Managed node 的檔案。group_vars/:設定 staging、production 等不同群組 (環境) 變數 ;若有共用變數的部份可寫在all檔案裡。setup.yml:include 各種 tasks 的主要 playbook。tasks/:將各種不同任務獨立出來的 tasks,在裡分別為restart_api.yml,setting_nginx.yml和setup.yml。templates/:集中管理要使用 templates module 複製到 Managed node 的檔案。
Jenkins 專案目錄結構範例
Jenkins 專案目錄結構範例
my-ansible/
├── LICENSE
├── README.md
├── Vagrantfile
├── ansible.cfg
|
├── inventory
|
├── docker-jenkins.yml
├── jenkins-ansible-lint.yml
├── playbook_example.yml
|
└── roles/
├── docker/
├── docker-jenkins/
│ ├── defaults/
│ │ └── main.yml
│ ├── files/
│ │ └── plugins.txt
│ ├── meta/
│ │ └── main.yml
│ ├── tasks/
│ │ ├── dependencies.yml
│ │ ├── main.yml
│ │ └── setup.yml
│ └── templates/
│ ├── Dockerfile.j2
│ └── security.groovy.j2
├── jenkins-ansible-lint/
└── pip/
- 根目錄舉凡
LICENSE,README.md,Vagrantfile以及ansible.cfg這類的說明、設定檔案,我都習慣將它們直接放在根目錄下。另外,由於在這個專案內我只有一個 inventory file,所以我也直接將其擺放在根目錄下,如果有多個 inventory files,還可以加入group_vars/以及host_vars/來定義不同環境下會用到的變數。除此之外,這個 Ansbile 專案內,我還放了三份不同的 playbook roles/在這裡我存放了所有跟這個專案有關的 roles。由於每個 role 的結構類似,所以我以其中的docker-jenkins這個 role 來做簡單介紹:defaults/在這個資料夾下,通常被用來定義優先度較低的變數。除了defaults/,習慣上我還會另外將只跟這個 role 有關的變數放在vars/的資料夾下來做使用目的上的區分。關於 Ansbile 變數的優先權,可以參考官方在這裡的說明文件files/這個資料夾內通常存放著這個 role 在部署過程中會需要使用或執行的檔案templates/由於 Ansible 是用 Python 開發的一個自動化工具,所以也原生支援 Jinja2 這套模版引擎 (templating engine)。與files/下的檔案不同,這個資料夾下的檔案通常都以.j2作為副檔名。Ansible 會根據執行環境、傳遞參數等等的不同在部署過程中來對 template file 做某種程度上調整。tasks/整個 role 中最核心的部分。這裡面定義了這個 role 的部署邏輯以及運行任務。在這個資料夾下可以不只有一個檔案,然後在main.yml裡定義何時呼叫其他檔案meta/meta/資料夾內定義了這個 role 的依賴 (dependencies) 關係。以這個docker-jenkins為例,docker這個 role 就是其依賴。在運行時,會在運行完meta/內定義的所有 dependencies 後才接著執行 role 本身的任務。我們可以充分利用這個特色來重複組合及利用已經定義好的 role 以減少重造輪子的情況發生handlers/我們會將所有 handlers 事件存放在這個目錄下。雖然這個專案並沒有使用到任何 handler,但 handler 是 Ansible 中非常好用的一個功能。我們可以根據 Ansible 運行時 tasks 狀態的改變來通知 (notify) handlers。最重要的特色是,無論有多少個 task notify 同一個 handler,該 handler 都只會運行一次。非常常見 handler 的實踐之一就是在檔案被修改後重啟 services
撰寫原則
- 透過
inventory和group_vars來定義 local, staging 和 production 等各環境的主機和變數。 - 儘可能的把重複的 tasks 獨立出來,然後讓 playbook 依不同需求 include 進來用。在這個例子裡,凍仁把
setup.yml和update_config.yml兩個 playbook 中重複的 tasks 獨立成tasks/setting_api.yml,並透過include重複使用。